/**
 * Wihidum - Efficient Broker Hierarchy for Publish Subscribe Middleware
 *
 * License      :   Apache License 2.0
 * Home Page    :   http://code.google.com/p/wihidum/
 * Mailing List :   wihidum@googlegroups.com
 */

package lk.mrt.cse.wihidum.subscriber.client;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * The UI of subscriber service client
 */
public class UserInterface
        extends JFrame {

    private Client client = new Client(this);

    private JTextField brokerAddress = new JTextField("http://localhost:8080/axis2/services/Wihidum-Broker-Service");
    private JTextField publisherAddress = new JTextField("");
    private JTextField listenerAddress = new JTextField("http://localhost:8080/axis2/services/Wihidum-Listener-Service");
    private JTextField subscriberAddress = new JTextField("http://localhost:8080/axis2/services/Wihidum-Subscriber-Service");
    private JTextField subscriptionID = new JTextField("");
    private JTextField topic = new JTextField();
    private JButton subscribeCommand = new JButton("Subscribe");
    private JButton unsuscribeCommand = new JButton("Unsubscribe");
    private JButton refreshCommand = new JButton("Refresh");
    private JButton cancelCommand = new JButton("Cancel");
    private JLabel informationBar = new JLabel("");
    private JTable publicationsTable = new JTable();
    private DefaultTableModel model = new DefaultTableModel() {
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    };
    private JScrollPane scrollPane = new JScrollPane();

    /**
     * Default constructor
     */
    public UserInterface() {
        initComponents();
    }

    /**
     * Add components to the UI
     */
    public void initComponents() {
        model.addColumn("Publisher");
        model.addColumn("Topic");
        model.addColumn("Publication");

        publicationsTable.setOpaque(false);
        publicationsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        scrollPane.setViewportView(publicationsTable);
        publicationsTable.setModel(model);

        JPanel inputPanel = new JPanel(new GridLayout(6, 2));
        inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 30, 10, 30));
        inputPanel.add(new JLabel("Broker Address"));
        inputPanel.add(brokerAddress);
        inputPanel.add(new JLabel("Publisher Address"));
        inputPanel.add(publisherAddress);
        inputPanel.add(new JLabel("Listener Address"));
        inputPanel.add(listenerAddress);
        inputPanel.add(new JLabel("Subscriber Address"));
        inputPanel.add(subscriberAddress);
        inputPanel.add(new JLabel("Wait Time"));
        inputPanel.add(subscriptionID);
        inputPanel.add(new JLabel("Subscriptions Count"));
        inputPanel.add(topic);

        JPanel infoPanel = new JPanel(new BorderLayout(0, 10));
        infoPanel.setBorder(BorderFactory.createEmptyBorder(10, 30, 10, 30));
        infoPanel.add(scrollPane, BorderLayout.CENTER);
        infoPanel.add(informationBar, BorderLayout.SOUTH);

        JPanel commandPanel = new JPanel(new GridLayout(1, 4));
        commandPanel.setBorder(BorderFactory.createEmptyBorder(10, 30, 10, 30));
        commandPanel.add(subscribeCommand);
        commandPanel.add(unsuscribeCommand);
        commandPanel.add(refreshCommand);
        commandPanel.add(cancelCommand);

        JPanel backPanel = new JPanel(new BorderLayout());
        backPanel.add(inputPanel, BorderLayout.NORTH);
        backPanel.add(infoPanel, BorderLayout.CENTER);
        backPanel.add(commandPanel, BorderLayout.SOUTH);
        this.setContentPane(backPanel);

        this.setSize(500, 500);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width - 400) / 2, (screenSize.height - 500) / 2, 500, 500);

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setTitle("Subscriber Service Client");

        subscribeCommand.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                subscribeActionPerformed(event);
            }
        });
        unsuscribeCommand.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                unsubscribeActionPerformed(event);
            }
        }
        );
        refreshCommand.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                refreshActionPerformed(event);
            }
        });

        cancelCommand.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                cancelActionPerformed(event);
            }
        });
    }

    public void clearTable() {
        while (model.getRowCount() > 0) {
            model.removeRow(0);
        }
    }

    public void newPublicationReceived(String publisher, String topic, String publication) {
        model.insertRow(model.getRowCount(), new Object[]{publisher, topic, publication});
    }

    public void showInfo(String info) {
        informationBar.setText(info);
        informationBar.setForeground(Color.BLUE);
        this.repaint();
    }

    public void showError(String info) {
        informationBar.setText(info);
        informationBar.setForeground(Color.RED);
        this.repaint();
    }

    private void refresh() {
        informationBar.setText("");
    }

    private void subscribeActionPerformed(ActionEvent event) {
        refresh();

        String subscriptionIDText = subscriptionID.getText();
        if (subscriptionIDText == null || subscriptionIDText.isEmpty()) {
            showError("Please set the milliseconds to wait");
        }

        String brokerEPR = brokerAddress.getText();
        if (brokerEPR == null || brokerEPR.isEmpty()) {
            showError("Please set the end point address of the broker service");
        }

        String listenerEPR = listenerAddress.getText();
        if (listenerEPR == null || listenerEPR.isEmpty()) {
            showError("Please set the end point address of the listener service");
        }

        String subscriberEPR = subscriberAddress.getText();
        if (subscriberEPR == null || subscriberEPR.isEmpty()) {
            showError("Please set the end point address of the subscriber service");
        }

        String topicText = topic.getText();
        if (topicText == null || topicText.isEmpty()) {
            showError("Please enter number of subscriptions");
        }

        String publisherEPR = publisherAddress.getText();

        Run run = new Run();
        run.brokerEPR = brokerEPR;
        run.publisherEPR = publisherEPR;
        run.listenerEPR = listenerEPR;
        run.subscriberEPR = subscriberEPR;
        try {
            run.wait = Integer.parseInt(subscriptionIDText);
            run.subscriptions = Integer.parseInt(topicText);
            run.start();
        }
        catch (NumberFormatException e) {
            showError("Error in data");
        }
    }

    private class Run extends Thread {

        int wait = 0;
        int subscriptions = 0;
        String subscriptionIDText;
        String brokerEPR;
        String publisherEPR;
        String listenerEPR;
        String subscriberEPR;
        String topicText;


        public void run() {

            String topics[] = new String[20];
            for (int i=0; i<20; i++) {
                topics[i] = "Topic" +i+ "";
            }

            for (int i = 0; i < subscriptions; i++) {
                subscriptionIDText = "" + i + "";

                topicText = topics[(int) (Math.random() * 20)];

                client.subscribe(subscriptionIDText, brokerEPR, publisherEPR, listenerEPR, subscriberEPR, topicText);
                try {
                    Thread.sleep(wait);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private void unsubscribeActionPerformed(ActionEvent event) {
        String subscriptionIDText = subscriptionID.getText();
        if (subscriptionIDText == null || subscriptionIDText.isEmpty()) {
            showError("Please set the identifier for the subscription");
        }
        String listenerEPR = listenerAddress.getText();
        if (listenerEPR == null || listenerEPR.isEmpty()) {
            showError("Please set the end point address of the listener service");
        }
        String topicText = topic.getText();
        if (topicText == null || topicText.isEmpty()) {
            showError("Please enter the topic to be subscribed");
        }
        client.unsusbcribe(listenerEPR, subscriptionIDText, topicText);
    }

    private void refreshActionPerformed(ActionEvent event) {
        refresh();

        String subscriptionIDText = subscriptionID.getText();
        if (subscriptionIDText == null || subscriptionIDText.isEmpty()) {
            showError("Please set the identifier of the subscription");
        }

        String listenerEPR = listenerAddress.getText();
        if (listenerEPR == null || listenerEPR.isEmpty()) {
            showError("Please set the end point address of the listener service");
        }

        String subscriberEPR = subscriberAddress.getText();
        if (subscriberEPR == null || subscriberEPR.isEmpty()) {
            showError("Please set the end point address of the subscriber service");
        }

        client.getPublications(subscriptionIDText, subscriberEPR, listenerEPR);
    }

    private void cancelActionPerformed(ActionEvent event) {
        System.exit(0);
    }

}
